/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.core.tapestry.services.assets;

import net.sf.ehcache.CacheManager;

import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.services.AssetResourceLocator;
import org.apache.tapestry5.internal.services.ResourceDigestManager;
import org.apache.tapestry5.internal.services.ResourceStreamer;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.InjectService;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.ioc.annotations.Marker;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.services.AssetFactory;
import org.apache.tapestry5.services.AssetPathConverter;
import org.apache.tapestry5.services.AssetSource;
import org.apache.tapestry5.services.BindingFactory;
import org.apache.tapestry5.services.Context;
import org.apache.tapestry5.services.Dispatcher;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;
import org.apache.tapestry5.services.assets.AssetRequestHandler;
import org.apache.tapestry5.upload.services.UploadSymbols;
import org.libermundi.theorcs.core.CoreConstants;
import org.libermundi.theorcs.core.tapestry.services.configuration.ApplicationConfig;
import org.libermundi.theorcs.core.util.OrcsHome;
import org.slf4j.Logger;

/**
 * <Briefly describing the purpose of the class/interface...>
 *
 */
public final class AssetModule {
    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration, ApplicationConfig appConfig) {
        configuration.add(UploadSymbols.FILESIZE_MAX, appConfig.getString(CoreConstants.UPLOAD_MAX_SIZE));
    }	
	
    public static void bind(ServiceBinder binder) {
        binder.bind(BindingFactory.class, OfsBindingFactory.class).withId("OfsBindingFactory");
        binder.bind(Dispatcher.class, OfsAssetDispatcher.class).withId("OfsAssetDispatcher");
        binder.bind(FileValidator.class,OfsFileValidator.class).withId("OfsFileValidator");
        binder.bind(AssetServices.class, AssetServicesImpl.class);
    }
	
    public static void contributeBindingSource(MappedConfiguration<String, BindingFactory> configuration,
                                    @InjectService("OfsBindingFactory") BindingFactory ofsBindingFactory) {
        configuration.add(OfsBindingFactory.OFS_BINDING_PREFIX, ofsBindingFactory);
    }
                                    
    
    public static void contributeAssetSource(
            MappedConfiguration<String, AssetFactory> configuration,
            @OrcsFileSystem AssetFactory ofsAssetFactory) {
        configuration.add(OfsAssetFactory.OFS_VIRTUAL_FOLDER, ofsAssetFactory);
    }
    
    @Marker(OrcsFileSystem.class)
    public static AssetResourceLocator buildOfsResourceLocator(ResourceDigestManager digestManager, Response response,
    		AssetSource assetSource, @OrcsFileSystem AssetFactory ofsAssetFactory ) {
    	return new OfsResourceLocator(digestManager, response, assetSource, ofsAssetFactory);
    }
    
    public static void contributeServiceOverride(MappedConfiguration<Class<?>, Object> configuration,
    		@Local AssetResourceLocator locator) {
    	configuration.add(AssetResourceLocator.class, locator);
    }

    @Marker(OrcsFileSystem.class)
    public static AssetRequestHandler buildOfsAssetRequestHandler(ResourceStreamer streamer, 
    		AssetResourceLocator assetResourceLocator){
    	return new OfsAssetRequestHandler(streamer, assetResourceLocator);
    }
    
    public static void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration, @InjectService("OfsAssetDispatcher") Dispatcher ofsAssetDispatcher) {
            configuration.add("OfsAsset", ofsAssetDispatcher, "after:Asset","before:ComponentEvent");
    }
    
    public static void contributeResourceDigestGenerator(Configuration<String> configuration){
    	configuration.add("ftl");
    }
    
	/*
	 * FileManager Services (QuickUploads)
	 */
    @Marker(OrcsFileSystem.class)
	public static FileManager buildQuickUploadFileManager(Logger logger, final OrcsHome orcsHomeDir,
			ApplicationConfig appConfig,
			@Local AssetResourceLocator resourceLocator,
			ImageCache imageCache,FileValidator fileValidator,
			@OrcsFileSystem AssetFactory assetFactory) {
		return new OfsFileManager(orcsHomeDir.getPath(), "uploads", resourceLocator, fileValidator, imageCache, assetFactory);
	}
	
	/*
	 * ImageCache
	 */
    @Marker(OrcsFileSystem.class)
	public static ImageCache buildImageCache(final OrcsHome orcsHomeDir, @Local AssetResourceLocator resourceLocator,
			ImageCache imageCache,FileValidator fileValidator, @Local AssetFactory assetFactory, CacheManager cacheManager){
		return new OfsImageCache(orcsHomeDir.getPath(), fileValidator, resourceLocator, assetFactory, cacheManager);
	}
	
    @Marker(OrcsFileSystem.class)
    public static AssetFactory buildOfsAssetFactory(
    				Request request,
                    Context context,
                    AssetPathConverter converter,
                    OrcsHome orcsHome,
                    @Symbol(SymbolConstants.ASSET_PATH_PREFIX) String t5AssetPathPrefix) {
        return new OfsAssetFactory(request, context, orcsHome.getPath(), t5AssetPathPrefix);
    }

}
